package com.jy.wms.service;

import com.jy.wms.common.SetStatus;
import com.jy.wms.common.UUIDUtils;
import com.jy.wms.common.annotions.BaseServiceDescribe;
import com.jy.wms.common.base.BaseService;
import com.jy.wms.common.base.ServiceException;
import com.jy.wms.dao.WmsDistributionMapper;
import com.jy.wms.pojo.*;
import com.jy.wms.dao.WmsBoxMapper;
import io.swagger.models.auth.In;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName: WmsBoxService.java
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @Author Jane
 * @Date Wed Oct 25 10:02:09 CST 2017
 */

@Service
public class WmsBoxService extends BaseService<WmsBoxMapper,WmsBox> {


    /**
     *装箱_Jane
     * @param ids 发运订单主键ID列表
     * @return int
     */
    @BaseServiceDescribe(moduleName = "装箱",btnName = "确认装箱")
    @Transactional
    public void casingContainerazation(List<String> ids,String ckid,String sshzid)throws Exception{
        for(String id:ids) {
            //根据ID查询So订单各种状态是否满足
            WmsShipmentOrder so = dao.baseSelectBySokey(id);
            /**(1)	SO状态为“部分分配”/“全部分配”
             (2)	装箱状态为“未装箱”/“部分装箱”
             (3)	拆单状态为“已拆单”
             (4)	货主管理中“是否切箱”选项为是。
             */
            if (("1".equals(so.getFyzt()) || "2".equals(so.getFyzt())) && ("0".equals(so.getZxzt()) || "1".equals(so.getZxzt())) && "1".equals(so.getCdzt()) && "1".equals(so.getZxqx())) {
                //	(6)根据发运订单找寻分配明细“是否装箱”状态为“未装箱”的分配明细信息。
                List<WmsDistribution> distributions = dao.seachDistribution(id);
                List<WmsDistribution> sx = new ArrayList<WmsDistribution>();
                Integer max = 0;
                for (WmsDistribution dis : distributions) {
                    max++;
                    //(8)对比拆单和分配数量
                    if (Integer.parseInt(dis.getFpsl()) == Integer.parseInt(dis.getCdsl())) {
                        //(8--1)拆单数量与未装箱分配数量相等------整箱标记为整箱 散箱标记为散箱
                        if ("0".equals(dis.getZslx())) {
                            //整箱标记为整箱
                            List<WmsDistribution> count=dao.seachDistributionByCdid(dis.getSscdid());
                            String xbh=GeneratorBoxNumber();
                            for(WmsDistribution d:count) {
                                WmsBox box = new WmsBox();
                                box.setId(UUIDUtils.uuid());
                                box.setSsfpid(d.getId());
                                box.setSsfydid(dis.getSsfydd());
                                box.setSsfymxid(dis.getSsfymxid());
                                box.setHpid(dis.getHpid());
                                box.setSl(d.getFpsl());
                                box.setXbh(xbh);
                                box.setZzxid("0");
                                box.setXxh(max);
                                box.setZslx("0");
                                box.setCkid(ckid);
                                dao.baseInsert(box);
                                WmsDistribution f = new WmsDistribution();
                                f.setId(dis.getId());
                                f.setZxzt("1");
                                dao.updateDistribution(f);
                            }


                        } else if ("1".equals(dis.getZslx())) {
                            //散箱标记需要拼箱
                            List<WmsDistribution> count=dao.seachDistributionByCdid(dis.getSscdid());
                            for(WmsDistribution d:count) {
                                sx.add(d);//散箱标记加入另外一个集合 等待拼箱
                            }
                        } else {
                            throw new ServiceException("拆单整散标记有误");
                        }
                    } else if (Integer.parseInt(dis.getFpsl()) < Integer.parseInt(dis.getCdsl())) {
                        List<WmsDistribution> count=dao.seachDistributionByCdid(dis.getSscdid());
                        //(8--2)	拆单数量大于未装箱分配数量------散箱
                        for(WmsDistribution d:count) {
                            sx.add(d);//都是散箱加入另外集合 等待拼箱
                        }
                    } else {
                        //(8--3)分配数量大于拆单数量理论不会出现这种情况 异常
                        throw new ServiceException("分配或拆单数据异常");
                    }
                }

                //整合散箱准备拼箱
                String hpType = "";//记录货品类型
                if (sx.size() > 0) {
                    Integer khfxh = 0;
                    for (WmsDistribution d : sx) {
                        Integer maxxh = dao.seachMaxXxhBySsfydid(id);//获取做大箱序号
                        WmsGoodsType sfhf = dao.selectGoodsSfhf(d.getHpid());
                        if ("0".equals(sfhf.getSfhf())) {
                            //不可以混放
                            if (hpType.equals(d.getZlid())) {
                                //即为一类货品可放到一起
                                WmsBox box = new WmsBox();
                                box.setId(UUIDUtils.uuid());
                                box.setCkid(ckid);
                                box.setSsfpid(d.getId());
                                box.setSsfydid(id);
                                box.setSsfymxid(d.getSsfymxid());
                                box.setHpid(d.getHpid());
                                box.setSl(d.getFpsl());
                                box.setXbh("");
                                box.setXxh(maxxh);
                                box.setZzxid("0");
                                box.setZslx("1");
                                dao.baseInsert(box);
                            } else {
                                //不是一类货品，单独放置
                                WmsBox box = new WmsBox();
                                box.setId(UUIDUtils.uuid());
                                box.setCkid(ckid);
                                box.setSsfpid(d.getId());
                                box.setSsfydid(id);
                                box.setSsfymxid(d.getSsfymxid());
                                box.setHpid(d.getHpid());
                                box.setSl(d.getFpsl());
                                box.setXxh(maxxh + 1);
                                box.setXbh("");
                                box.setZzxid("0");
                                box.setZslx("1");
                                dao.baseInsert(box);
                            }
                            hpType = d.getZlid();//记录货品类型
                        } else if ("1".equals(sfhf.getSfhf())) {
                            //可以混放
                            WmsBox box = new WmsBox();
                            box.setId(UUIDUtils.uuid());
                            box.setCkid(ckid);
                            box.setSsfpid(d.getId());
                            box.setSsfydid(id);
                            box.setSsfymxid(d.getSsfymxid());
                            box.setHpid(d.getHpid());
                            box.setSl(d.getFpsl());
                            box.setXbh("");
                            box.setZzxid("0");
                            if (khfxh == 0) {
                                box.setXxh(maxxh + 1);
                                khfxh = maxxh + 1;
                            } else {
                                box.setXxh(khfxh);
                            }
                            box.setZslx("1");
                            dao.baseInsert(box);
                        } else {
                            throw new ServiceException("货品混放标记异常");
                        }
                        WmsDistribution d1 = new WmsDistribution();
                        d1.setId(d.getId());
                        d1.setZxzt("1");
                        dao.updateDistribution(d1);
                    }

                    //装箱
                    //获取要装箱的总体积和总重量,根据箱序号区分是否一箱
                    List<WmsBox> ztj = dao.seachZtjAndZzl(id);
                    for (WmsBox box : ztj) {
                        //获取周转箱的信息
                        WmsBox NoBhBox = dao.seachNoXbhBySsfydid(id, box.getXxh());//获取此编号下货品最大长宽高
                        List<WmsTurnoverBox> turnoverBoxes = dao.seachTurnoverMx(sshzid, ckid, NoBhBox.getGoodsC(), NoBhBox.getGoodsK(), NoBhBox.getGoodsG());
                        if (turnoverBoxes.size() > 0) {
                            Double tj = Double.parseDouble(box.getZtj());//记录货品体积
                            Double zl = Double.parseDouble(box.getZzl());//记录货品重量
                            //根据体积和重量来选择箱子
                            String jl = "";//记录箱
                            List<String> xid = new ArrayList<>();
                            do {
                                for (int i = 0; i < turnoverBoxes.size(); i++) {
                                    //货品总体积大于箱体积 则选择一个大箱子
                                    if (tj >= Double.parseDouble(turnoverBoxes.get(i).getKytj()) && zl >= Double.parseDouble(turnoverBoxes.get(i).getZdtj())) {
                                        if ("".equals(jl)) {
                                            Map<String, Object> map = new HashMap<>();
                                            xid.add(turnoverBoxes.get(i).getId());
                                            tj -= Double.parseDouble(turnoverBoxes.get(i).getKytj());
                                            zl -= Double.parseDouble(turnoverBoxes.get(i).getZdzl());
                                        } else {
                                            Map<String, Object> map = new HashMap<>();
                                            tj = 0d;
                                            zl = 0d;
                                            xid.add(turnoverBoxes.get(i).getId());
                                            jl = "";
                                            break;//次序号货品添加完成。进入下一个循环
                                        }
                                    } else if (tj <= Double.parseDouble(turnoverBoxes.get(i).getKytj()) && zl >= Double.parseDouble(turnoverBoxes.get(i).getZdtj())) {
                                        if ("".equals(jl)) {
                                            Map<String, Object> map = new HashMap<>();
                                            xid.add(turnoverBoxes.get(i).getId());
                                            tj = 0D;
                                            zl -= Double.parseDouble(turnoverBoxes.get(i).getZdzl());
                                        } else {
                                            Map<String, Object> map = new HashMap<>();
                                            tj = 0d;
                                            zl = 0d;
                                            xid.add(turnoverBoxes.get(i).getId());
                                            jl = "";
                                            break;//次序号货品添加完成。进入下一个循环
                                        }
                                    } else if (tj >= Double.parseDouble(turnoverBoxes.get(i).getKytj()) && zl <= Double.parseDouble(turnoverBoxes.get(i).getZdtj())) {
                                        if ("".equals(jl)) {
                                            Map<String, Object> map = new HashMap<>();
                                            xid.add(turnoverBoxes.get(i).getId());
                                            tj -= Double.parseDouble(turnoverBoxes.get(i).getKytj());
                                            zl = 0D;
                                        } else {
                                            Map<String, Object> map = new HashMap<>();
                                            tj = 0d;
                                            zl = 0d;
                                            xid.add(turnoverBoxes.get(i).getId());
                                            jl = "";
                                            break;//次序号货品添加完成。进入下一个循环
                                        }
                                    } else {
                                        //货品体积和重量都小于怎记录
                                        jl = turnoverBoxes.get(i).getId();
                                    }
                                    //如果所有体积和重量都不超过，并且最小的箱子都装不满，即用最小的箱子
                                    if (i == (turnoverBoxes.size() - 1)) {
                                        if ((jl != "") && (tj == Double.parseDouble(box.getZtj())) && (zl == Double.parseDouble(box.getZzl()))) {
                                            Map<String, Object> map = new HashMap<>();
                                            tj = 0d;
                                            zl = 0d;
                                            xid.add(turnoverBoxes.get(i).getId());
                                            jl = "";
                                            break;//次序号货品添加完成。进入下一个循环
                                        }
                                    }
                                }

                            } while (tj > 0d && zl > 0d);
                            //给此条明细装箱
                            if (xid.size() == 1) {//如果一个箱就可直接装箱
                                WmsBox boxxbh = new WmsBox();
                                boxxbh.setXbh(GeneratorBoxNumber());
                                boxxbh.setZzxid(xid.get(0));
                                boxxbh.setXxh(box.getXxh());
                                boxxbh.setSsfydid(id);
                                dao.updateXbh(boxxbh);
                            } else if (xid.size() > 1) {//一个箱以上计算装箱
                                for (String x : xid) {
                                    String xbh = GeneratorBoxNumber();
                                    WmsTurnoverBox tbox = dao.zzxXx(x);
                                    Double ttj = Double.parseDouble(tbox.getKytj());
                                    Double tzl = Double.parseDouble(tbox.getZdzl());
                                    List<WmsBox> boxxx = dao.seachBoxMxByxxh(id, box.getXxh());//查询箱明细
                                    for (WmsBox b : boxxx) {
                                        //计算重量和体积整除
                                        Double tsl = ttj / Double.parseDouble(b.getGoodsTj());
                                        Double zsl = tzl / Double.parseDouble(b.getGoodsZl());
                                        if (Integer.parseInt(b.getSl()) <= tsl.intValue() && Integer.parseInt(b.getSl()) <= zsl.intValue()) {
                                            b.setXbh(xbh);
                                            b.setZzxid(x);
                                            dao.baseUpdateByPrimaryKeySelective(b);
                                        } else if (Integer.parseInt(b.getSl()) >= tsl.intValue() && Integer.parseInt(b.getSl()) <= zsl.intValue()) {
                                            //新增一条明细
                                            WmsBox cbox = new WmsBox();
                                            cbox.setId(UUIDUtils.uuid());
                                            cbox.setSl(tsl.toString());
                                            cbox.setXbh(xbh);
                                            cbox.setXxh(b.getXxh());
                                            cbox.setCkid(b.getCkid());
                                            cbox.setSsfydid(b.getSsfydid());
                                            cbox.setSsfpid(b.getSsfpid());
                                            cbox.setSsfymxid(b.getSsfymxid());
                                            cbox.setHpid(b.getHpid());
                                            box.setZzxid(x);
                                            box.setZslx("1");
                                            dao.baseInsert(box);
                                            //更新剩余数量
                                            Integer ssl = Integer.parseInt(b.getSl()) - tsl.intValue();
                                            b.setSl(ssl.toString());
                                            dao.baseUpdateByPrimaryKeySelective(b);
                                        } else if (Integer.parseInt(b.getSl()) <= tsl.intValue() && Integer.parseInt(b.getSl()) >= zsl.intValue()) {
                                            //新增一条明细
                                            WmsBox cbox = new WmsBox();
                                            cbox.setId(UUIDUtils.uuid());
                                            cbox.setSl(zsl.toString());
                                            cbox.setXbh(xbh);
                                            cbox.setXxh(b.getXxh());
                                            cbox.setCkid(b.getCkid());
                                            cbox.setSsfydid(b.getSsfydid());
                                            cbox.setSsfpid(b.getSsfpid());
                                            cbox.setSsfymxid(b.getSsfymxid());
                                            cbox.setHpid(b.getHpid());
                                            box.setZzxid(x);
                                            box.setZslx("1");
                                            dao.baseInsert(box);
                                            //更新剩余数量
                                            Integer ssl = Integer.parseInt(b.getSl()) - zsl.intValue();
                                            b.setSl(ssl.toString());
                                            dao.baseUpdateByPrimaryKeySelective(b);
                                        } else if (Integer.parseInt(b.getSl()) >= tsl.intValue() && Integer.parseInt(b.getSl()) >= zsl.intValue()) {
                                            Integer ssl = tsl.intValue() < zsl.intValue() ? tsl.intValue() : zsl.intValue();
                                            //新增一条明细
                                            WmsBox cbox = new WmsBox();
                                            cbox.setId(UUIDUtils.uuid());
                                            cbox.setSl(ssl.toString());
                                            cbox.setXbh(xbh);
                                            cbox.setXxh(b.getXxh());
                                            cbox.setCkid(b.getCkid());
                                            cbox.setSsfydid(b.getSsfydid());
                                            cbox.setSsfpid(b.getSsfpid());
                                            cbox.setSsfymxid(b.getSsfymxid());
                                            cbox.setHpid(b.getHpid());
                                            box.setZzxid(x);
                                            box.setZslx("1");
                                            dao.baseInsert(box);
                                            //更新剩余数量
                                            Integer sysl = Integer.parseInt(b.getSl()) - ssl;
                                            b.setSl(sysl.toString());
                                            dao.baseUpdateByPrimaryKeySelective(b);
                                        } else {
                                            throw new ServiceException("数据有误请检查基础数据");
                                        }
                                    }
                                }

                            }

                        } else {
                            throw new ServiceException("周转箱不足或货品尺寸超标不可装箱");
                        }

//                            //判断最后一箱的体积是或否小于前一箱的浮动容积 小于则 放如前一箱  大于则单独装一箱
//                            List<WmsBox> box = dao.seachBoxByMaxXxh(id);//获取最后一箱的信息
//                            WmsBox zdtj = dao.seachZhyxTj(id);//获取积最后一箱的体积
//                            List<WmsBox> dd = dao.selectByzzxid(id);//获取零散周转箱ID
//                            if(dd.size()>1){
//                            for (WmsBox b : dd) {
//                                WmsTurnoverBox tb = dao.seachTurnoverXX(b.getZzxid());
//                                if (Double.parseDouble(tb.getFdrj()) > Double.parseDouble(zdtj.getZtj())) {
//                                    //放入这个箱子 最后一个箱子取消
//                                    for (WmsBox x : box) {
//                                        WmsBox ox = new WmsBox();
//                                        ox.setId(x.getId());
//                                        ox.setZzxid(b.getZzxid());
//                                        dao.baseUpdateByPrimaryKeySelective(ox);
//                                    }
//                                    break;
//                                }
//                            }
//                        }else{
//                                //只有一个箱子则给最后一个箱子写上箱信息
//                                WmsTurnoverBox boxmin=dao.seachZxtjBox(sshzid,ckid);
//                                for (WmsBox x : box) {
//                                    WmsBox ox = new WmsBox();
//                                    ox.setId(x.getId());
//                                    ox.setXbh(GeneratorBoxNumber());
//                                    ox.setZzxid(boxmin.getId());
//                                    dao.baseUpdateByPrimaryKeySelective(ox);
//                                }
//                            }
                        //                     }
//                        //修改箱序号
//                        List<WmsBox> wmsBoxes = dao.seachSx(id);
//                        String xbh = "";
//                            for (WmsBox wms : wmsBoxes) {
//                                if (xbh.equals(wms.getXbh())) {
//                                    WmsBox b = new WmsBox();
//                                    b.setId(wms.getId());
//                                    b.setXxh(dao.seachMaxXxhBySsfydid(id));
//                                    dao.baseUpdateByPrimaryKeySelective(b);
//                                } else {
//                                    xbh = wms.getXbh();
//                                    WmsBox b = new WmsBox();
//                                    b.setId(wms.getId());
//                                    b.setXxh(dao.seachMaxXxhBySsfydid(id)+1);
//                                    dao.baseUpdateByPrimaryKeySelective(b);
//                                }
//                            }

                        //修改发运单的装箱状态
                        List<WmsShipmentOrderDetailed> orderDetaileds = dao.selectShipmentByMxid(id);
                        int bf = 0;
                        int qb = 0;
                        int qt = 0;
                        for (WmsShipmentOrderDetailed shipmentOrderDetailed : orderDetaileds) {
                            Integer k = dao.selecBoxByFymxid(shipmentOrderDetailed.getId());
                            if (Integer.parseInt(shipmentOrderDetailed.getYqsl()) > k && k > 0) {
                                bf = 1;
                            } else if (Integer.parseInt(shipmentOrderDetailed.getYqsl()) == k) {
                                qb = 1;
                            } else {
                                qt = 1;
                            }
                        }
                        WmsShipmentOrder order = new WmsShipmentOrder();
                        order.setId(id);
                        Integer max1 = dao.boxMaxXh(id);
                        if (max1 > 5) {
                            order.setCyslb("2");
                        } else {
                            order.setCyslb("1");
                        }
                        if (qb == 1 && bf == 0 && qt == 0) {
                            order.setZxzt("2");
                            dao.updateShipmentOrder(order);
                        } else if (bf == 1) {
                            order.setZxzt("1");
                            dao.updateShipmentOrder(order);
                        }
                    }
                }
            }else{
                throw new ServiceException("所选订单不符合装箱要求，不可装箱");
            }
        }
    }
    /**
     *生成箱编号（生成箱编号）
     * @return int
     */
    @BaseServiceDescribe(moduleName = "装箱",btnName = "生成箱编号")
    public String GeneratorBoxNumber()throws  ServiceException{
        int num;
        int fnum;
        String xbh;
        try {
            do {
                Random random=new Random();
                num = random.nextInt(999-100+1)+100;
                SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmss");
                Date time = new Timestamp(System.currentTimeMillis());
                String xbhno = sdf.format(time);
                xbh ="X"+xbhno + num;
                fnum = dao.selectCountXbh(xbh);
            } while (fnum != 0);
            return xbh;
        } catch (Exception e) {
            throw new ServiceException("生成箱编号失败",e);
        }
    }
    /**
     * 分页查询
     * @param entity 实体
     * @return Page<WmsBox>
     */
    @BaseServiceDescribe(moduleName = "装箱",btnName = "分页查询装箱信息")
    public JSONObject selectZxmxByFydid (WmsBox entity )throws ServiceException{
        JSONObject json = new JSONObject();
        Page<WmsBox> lists=new Page<WmsBox>();
        PageHelper.startPage(entity.getPage(),entity.getRows());
        lists=(Page<WmsBox>)dao.selectZxmxByFydid(entity);
        if(lists.size()>0) {
            for (WmsBox box : lists) {
                if ("散箱".equals(box.getZslx())) {
                    List<WmsBox> boxMx = dao.selectDyOneXxByFydid(box.getSsfydid(), box.getXbh());
                    box.setBoxMx(boxMx);
                }
                box.setZzl(dao.xzl(box.getSsfydid(), box.getXxh()).toString());
            }
            json = SetStatus.setSearchType(JSONArray.fromObject(lists).toString(), (int) lists.getTotal());
            json.put("sobh", lists.get(0).getSobh());
            Double xzzl = 0d;

            json.put("xzzl", dao.xzl(lists.get(0).getSsfydid(), 0));
            json.put("sxs", dao.sxXs(lists.get(0).getSsfydid()));
            json.put("zxs", dao.zxXs(lists.get(0).getSsfydid()));

            return json;
        }else{
            throw new ServiceException("查询信息失败");
        }
    }
    /**
     * 查询装箱打印信息（发运单ID）_Jane
     * @param ssfydid 发运订单ID
     * @return Page<WmsBox>
     */
    @BaseServiceDescribe(moduleName = "装箱",btnName = "打印装箱信息")
    public JSONObject selectDyxxByFydid(String ssfydid,String ckmc,String show_rent,String telephone,String dz){
        JSONObject json = new JSONObject();
        List<WmsBox> list = new ArrayList<>();
        list=dao.selectDyxxByFydid(ssfydid);
        for (WmsBox wmsBox : list) {
            if("散箱".equals(wmsBox.getZslx())) {
                List<WmsBox> boxMx = dao.selectDyOneXxByFydid(ssfydid, wmsBox.getXbh());
                wmsBox.setBoxMx(boxMx);
            }
            wmsBox.setCkmc(ckmc);
            wmsBox.setShow_rent(show_rent);
            wmsBox.setKhdz(dz);
            wmsBox.setCkdh(telephone);
        }
        json = SetStatus.setSearchType(JSONArray.fromObject(list).toString(),(int) list.size());
        return json;
    }
    /**
     * 取消装箱_Jane
     * @param ids 所属发运订单ID
     * @return Page<WmsBox>
     */
    @BaseServiceDescribe(moduleName = "装箱",btnName = "取消装箱")
    @Transactional
    public void cancelEncasement(List<String> ids)throws Exception {
        for(String id:ids) {
            String jhzt = dao.seachShipmentJhzt(id);
            if("0".equals(jhzt)){
                Integer count = dao.baseDeleteByPrimaryKey(id);
                if (count > 0) {
                    //更新分配表装箱状态
                    List<WmsShipmentOrderDetailed> detaileds=dao.selectShipmentByMxid(id);
                    WmsDistribution distribution=null;
                    for(WmsShipmentOrderDetailed detailed:detaileds){
                        distribution=new WmsDistribution();
                        distribution.setSsfymxid(detailed.getId());
                        distribution.setZxzt("0");
                        dao.updateWmsDistribution(distribution);
                    }
                    WmsShipmentOrder order = new WmsShipmentOrder();
                    order.setId(id);
                    order.setCyslb("0");
                    order.setZxzt("0");
                    dao.updateShipmentOrder(order);
                } else {
                    throw new ServiceException("此订单没有装箱明细，取消装箱失败");
                }
            }else {
                throw new ServiceException("此订单已捡货不能取消");
            }
        }

    }
}
